from flask import abort,current_app, jsonify,render_template,request,session
from flask import g

from info import db
from info.models import News, User, Comment, CommentLike
from info.utils.commons import user_login_data
from info.utils.response_code import RET
from . import news_blue


# 评论点赞
# 请求路径: /news/comment_like
# 请求方式: POST
# 请求参数:news_id,comment_id,action,g.user
# 返回值: errno,errmsg
@news_blue.route('/comment_like', methods=['POST'])
@user_login_data
def comment_like():
    # 判断用户是否登录
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg="用户未登录")
    # 获取参数
    comment_id = request.json.get("comment_id")
    action = request.json.get("action")

    # 参数类型校验，为空校验
    if not all([comment_id,action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不全")

    # 操作类型校验
    if action not in ["add","remove"]:
        return jsonify(errno=RET.DATAERR, errmsg="操作类型错误")

    # 根据评论编号获取评论对象，
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取评论失败")

    # 判断评论是否存在
    if not comment:return jsonify(errno=RET.NODATA, errmsg="评论对象不存在")

    try:
        # 根据造作类型，点赞和取消点赞
        if action == "add":
            # 判断当前用户是否对该评论点过赞
            comment_like = CommentLike.query.filter(CommentLike.comment_id == comment_id,
                                                    CommentLike.user_id == g.user.id).first()
            if not comment_like:
                comment_like = CommentLike()
                comment_like.comment_id = comment_id
                comment_like.user_id = g.user.id

                comment.like_count += 1

                db.session.add(comment_like)
                db.session.commit()
        else:
            # 判断当前用户是否对该评论点过赞
            comment_like = CommentLike.query.filter(CommentLike.comment_id == comment_id,
                                                    CommentLike.user_id == g.user.id).first()
            if comment_like:
                # 移除点赞对象
                db.session.delete(comment_like)
                # 点赞对象减1
                if comment.like_count > 0:
                    comment.like_count -= 1

                db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据库操作有误")

    return jsonify(errno=RET.OK, errmsg="评论成功")







# 新闻评论后端
# 请求路径: /news/news_comment
# 请求方式: POST
# 请求参数:news_id,comment,parent_id, g.user
# 返回值: errno,errmsg,评论字典
@news_blue.route('/news_comment', methods=['POST'])
@user_login_data
def new_comment():
    # 判断用户是否登录
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg="用户未登录")
    # 获取参数
    news_id = request.json.get("news_id")
    content = request.json.get("comment")
    parent_id = request.json.get("parent_id")

    # 参数为空校验
    if not all([news_id,content]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不全")

    # 创建评论对象
    comment = Comment()

    # 设置评论属性
    comment.user_id = g.user.id
    comment.news_id = news_id
    comment.content = content
    # 判断是否有父id，有则添加属性
    if parent_id:
        comment.parent_id = parent_id

    # 将评论对象添加到数据库中
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="数据存储失败")

    return jsonify(errno=RET.OK, errmsg="成功",data = comment.to_dict())

# 12.收藏功能接口
# 请求路径: /news/news_collect
# 请求方式: POST
# 请求参数:news_id,action, g.user
# 返回值: errno,errmsg

@news_blue.route('/news_collect', methods=['POST'])
@user_login_data
def news_collect():
    # # 判断用户是否登录
    # user_id = session.get("user_id")
    #
    # user = None
    #
    # if user_id:
    #     try:
    #         # 获取用户登录数据
    #         from info.models import User
    #         user = User.query.get(user_id)
    #     except Exception as e:
    #         current_app.logger.error(e)
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg="该用户未登录")
    # 获取参数
    news_id = request.json.get("news_id")
    action = request.json.get("action")
    #校验参数是否为空
    if not all([news_id,action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不全")

    # 操作类型校验
    if action not in ["collect","cancel_collect"]:
        return jsonify(errno=RET.DATAERR, errmsg="操作类型有误")

    # 根据新闻编号取出新闻对象
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET,errmsg="")

    # 判断新闻对象是否存在
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻获取失败")

    # 根据操作类型，选择收藏或取消收藏操作
    try:

        if action == "collect":
            if not news in g.user.collection_news:
                g.user.collection_news.append(news)

        else:
            if news in g.user.collection_news:
                g.user.collection_news.remove(news)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据操作失败")

    # 返回响应
    return jsonify(errno=RET.OK, errmsg="收藏成功")


# 10.新闻详情展示(用户)
# 请求路径: /news/<int:news_id>
# 请求方式: GET
# 请求参数:news_id
# 返回值: detail.html页面, 用户data字典数据
# 新闻收藏显示
# 请求路径: /news/<int:news_id>
# 请求方式: GET
# 请求参数:news_id
# 返回值: detail.html页面, 用户,新闻, 热门新闻,收藏标记data字

# 新闻评论列表
# 请求路径: /news/<int:news_id>
# 请求方式: GET
# 请求参数:news_id
# 返回值: detail.html页面, 用户,新闻, 热门新闻,收藏标记,新闻评论,data字典数据
@news_blue.route('/<int:news_id>')
@user_login_data
def news_detail(news_id):
    # 获取用户登录状态,取session的值用get方法，不会发生错误
    # user_id = session.get("user_id")
    #
    # user = None
    #
    # if user_id:
    #     try:
    #         # 获取用户登录数据
    #         user = User.query.get(user_id)
    #     except Exception as e:
    #         current_app.logger.error(e)

    # 根据参数news_id获取新闻对象
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据读取失败")

    # 判断新闻用户是否存在
    if not news:
        abort(404)

    # 判断用户是否收藏新闻
    is_collected = False
    if g.user and news in g.user.collection_news:
        is_collected = True


    # 排行榜前五条新闻
    try:
        news_list = News.query.order_by(News.clicks.desc()).limit(5).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据读取失败")

    # 获取新闻对象
    click_news_list = []
    for new in news_list:
        click_news_list.append(new.to_dict())

    # 获取评论对象列表
    try:
        content = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET,errmsg="")

    # 保存用户点赞点赞列表
    comment_like_ids = []
    # 如果用户存在
    if g.user:
        try:
            # 获取用户所有点赞对象
            comment_likes = CommentLike.query.filter(CommentLike.user_id == g.user.id).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR,errmsg="获取点赞对象失败")

        # 遍历获取用户点赞过的评论编号
        for comment_like in comment_likes:
            comment_like_ids.append(comment_like.comment_id)


    # 获取评论对象
    comment_info = []
    for comment in content:
        comment_dict = comment.to_dict()
        # 假设用户对所有评论都没有点过赞
        comment_dict["is_like"] = False
        # 判断用户是否点赞
        if g.user and comment.id in comment_like_ids:
            comment_dict["is_like"] = True

        comment_info.append(comment_dict)


    data = {
         "news_info":news.to_dict(),
        "user_info":g.user.to_dict() if g.user else "",
        "click_news_list":click_news_list,
        "is_collected":is_collected,
        "commnet_info":comment_info
    }
    # 携带新闻数据，渲染页面
    return render_template("news/detail.html",data = data)

